const Koa = require('koa'),
    router = require('koa-router')(),
    render = require('koa-art-template')
path = require('path'),
    static = require('koa-static'),
    admin = require('./routers/admin'),
    koaBody = require('koa-body'),
    session = require('koa-session'),
    fs = require('fs');

const app = new Koa();

// 中间件  
// 配置art-template   所有模板文件放入view下
render(app, {
    root: path.join(__dirname, 'view'),
    extname: '.html',
    debug: process.env.NODE_ENV !== 'production'
});

// 配置静态资源
app.use(static('static'));

// 配置koa-body接受前端的请求体数据
app.use(koaBody({
    multipart: true
}));

// 配置session    cooklie中的key值
app.keys = ['some secret hurr'];

const CONFIG = {
    key: 'koa.sess',
    /** (string) cookie key (default is koa.sess) */
    /** (number || 'session') maxAge in ms (default is 1 days) */
    /** 'session' will result in a cookie that expires when session/browser is closed */
    /** Warning: If a session cookie is stolen, this cookie will never expire */
    // 默认有效期1天
    maxAge: 86400000,

    autoCommit: true,
    /** (boolean) automatically commit headers (default true) */
    //     能不能写
    overwrite: true,
    /** (boolean) can overwrite or not (default true) */
    //   cookie是否只有服务端可以访问
    httpOnly: true,
    /** (boolean) httpOnly or not (default true) */
    //   签名
    signed: true,
    /** (boolean) signed or not (default true) */
    //   
    rolling: false,
    /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */
    //是否可以覆盖，到期前进行访问，更新到期时间
    renew: false,
    /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/
    //   使用https进行访问 ，需要改成http改成false
    secure: false,
    /** (boolean) secure cookie*/
    sameSite: null,
    /** (string) session cookie sameSite options (default null, don't set it) */
};

app.use(session(CONFIG, app));
// or if you prefer all default config, just use => app.use(session(app));


// 路由
//404页面不存在（中间件）

app.use(async (ctx, next) => {
    await next();
    if (ctx.status === 404) {
        ctx.body = "抱歉，页面不存在";
    }
})

//根
router.get('/', ctx => {
    // 模板文件名
    ctx.render("home");
    // ctx.body="<div><h2>首页</h2></div>"
    console.log('home');
})

// 文件操作
router.get('/handlerfile', ctx => {

    // 根地址
    let root = __dirname;
    console.log(root);

    /* 
        //1. 判断是目录还是文件   操作方法不同
        let dst = root + '/view';
        // 异步写法
        fs.stat(dst, (err, stats) => {
            if (err) {
                // 比如不存在
                console.log(err);
            } else {
                if (stats.isFile()) {
                    console.log("是文件");
                }
                if (stats.isDirectory) {
                    console.log("是目录");
                }
            }
        });
        同步
        let stats = fs.statSync(dst);
        if (stats.isDirectory()) {
            console.log('同步---是目录');
        }
        if (stats.isFile()) {
            console.log('同步----是文件');
        } */

    // 2.判断文件或者目录是否存在
    /*   let dst = root + '/view';
      // 异步操作
      fs.exists(dst, (x) => {
          if (x) {
              console.log("存在");
          } else {
              console.log('不存在');
          }
      });
      // 同步
      let res = fs.existsSync(dst);
      if (res) {
          console.log("同步----存在");
      } else {
          console.log('同步----不存在');
      } */


    // 3.创建目录  注意：1.不能一次性创建多级目录 a/b/c/d
    /*   let dst = root + '/demo1/a';

    //2. 先判断文件是否存在
    // 不存在就创建
    if (!fs.existsSync(dst)) {
        // 异步
        // fs.mkdir(dst, err => {
        //     if (err) {
        //         console.log(err);
        //     } else {
        //         console.log('目录已创建');
        //     }
        // })

        // 同步的方式
        try {
            fs.mkdirSync(dst)
        } catch (err) {
            console.log(err);
        }

    } else {
        ctx.body = '目录已经存在'
    }
 */
    // 4.读取目录
    // let dst = root + '/static'
    // fs.readdir(dst, (err, files) => {
    //     if (err) {
    //         console.log(err);
    //     } else {
    //         // 只读取了文件，没有读取目录
    //         console.log(files);
    //     }
    // })

    // 传入的是一个地址
    /*  function readDir(dir) {
         // 判断是文件还是目录
         let isfd = fs.statSync(dir);
         if (isfd.isFile()) {
             console.log(dir);
         }
         // 目录
         if (isfd.isDirectory()) {
             console.log(dir);
             // 读取目录
             let res = fs.readdirSync(dir);
             // 遍历数组
             for (let i = 0; i < res.length; i++) {
                 // item可能是一个文件或者是一个目录，进行递归
                 // 递归之前路径需要添加
                 let item = dir + '/' + res[i];

                 // 进行递归
                 readDir(item);
                 
             }
         }
     }

     readDir(dst); */
    /*
        //5.删除目录
        // 注意：不可以删除一个非空目录,
        let dst = root + '/demo1';
        // if (fs.existsSync(dst)) {
        //     fs.rmdir(dst, err => {
        //         if (err) {
        //             console.log(err);
        //         } else{
        //             console.log('目录删除成功!');
        //         }
        //     })
        // }

        // 递归删除目录
        function delDir(dir) {
            // 判断是否存在目录
            if (fs.existsSync(dir)) {
                //判断是目录还是文件
                if (fs.statSync(dir).isDirectory()) {
                    // 是目录 进行遍历
                    let items = fs.readdirSync(dir);
                    for (let i = 0; i < items.length; i++) {
                        // 判断地址是文件还是目录
                        let item = dir + '/' + items[i];

                        if (fs.statSync(item).isDirectory()) {
                            // 是目录进行递归
                            delDir(item);
                        } else {
                            // 是文件则删除
                            fs.unlinkSync(item);
                        }

                    }
                    if (fs.existsSync(dir)) {
                        fs.rmdirSync(dir);
                    }
                }

                if (fs.existsSync(dir)) {

                    if (fs.statSync(dir).isFile()) {
                        // 是文件 删除
                        fs.unlinkSync(dir);
                    }
                }
            }


        }

        delDir(dst);
    */
    // 6.创建文件  
    // let dst = root + '/test.txt';
    //6.1 使用writeFile创建 （清空原有的内容） 内容被覆盖
    // 异步
    // fs.writeFile(dst, '使用writeFile方法进行创建', (err) => {
    //     if (err) {
    //         console.log(err);
    //     } else {
    //         console.log("文件创建成功");
    //         // 因为是异步函数，不进行显示
    //         ctx.body ="文件创建成功"
    //     }
    // })
    // 同步
    // try {

    //     fs.writeFileSync(dst,'使用同步传入的值');
    //     ctx.body = "文件创建成功";
    //     console.log("文件创建成功控制台同步");
    // } catch (err) {
    //     console.log(err);
    // }
    // 6.2如果文件不存在 则创建  追加内容 appendFile
    // try {
    //     fs.appendFileSync(dst,'你好，时使用追加的方式进行创建\n')
    // } catch (err) {
    //     console.log(err);
    // }

    /*
    //7.读取文件内容
    let dst = root + '/test.txt';
    // 判断是否存在，是否是文件
    if (fs.existsSync(dst)&&fs.statSync(dst).isFile()) {

        // 异步
        fs.readFile(dst, 'utf-8', (err, data) => {
            if (err) {
                console.log(err);
            } else {
                console.log(data);
            }
        })
        // 同步
        try {    
            let res = fs.readFileSync(dst, 'utf-8')
            console.log(res);
        } catch (err) {
            console.log(err);
        }

    } else {
        console.log('文件不存在');
    }
    */
/* 
    // 8.文件的删除
    let dst = root + '/test.txt';
    if (fs.existsSync(dst) && fs.statSync(dst).isFile()) {
        fs.unlink(dst, err => {
            if (err) {

                console.log(err);
            } else {
                console.log('删除成功');
            }
        })

        // 同步unlinkSync
        fs.unlinkSync(dst, err => {
            if (err) {

                console.log(err);
            } else {
                console.log('删除成功');
            }
        })
    } else {
        console.log('文件不存在或者类型错误');
    }
 */
    
/*
    // 9.文件重命名 可以改变路径 重命名  不可以读取二进制文件
    let dst = root + '/a.html';
    let newName = root + '/view/b.html';

    if (fs.existsSync(dst) && fs.statSync(dst).isFile()) {
        // 异步
        fs.rename(dst, newName, err => {
            if (err) {
                console.log(err);
            } else {
                console.log(dst+'重命名成功为'+newName);
            }
        })
        // 同步
        fs.renameSync()

    } else {
        console.log('文件不存在或类型错误');
    }
    */
    //10.管道流  实现文件的重命名或拷贝 更改路径       二进制读取到另外一个文件 适合做文件的上传
    let dst1 = root + '/view/b.html';
    let dst2 = root + '/c.html';
    // 创建可读流
    let readStream = fs.createReadStream(dst1);
    // 创建可写入流
    let writeStream = fs.createWriteStream(dst2);

    // 管道
    if (readStream.pipe(writeStream)) {
        console.log("拷贝成功");
    };
})


router.use("/admin",admin)


// 配置路由（建议写在开启服务器的前面）
app
    .use(router.routes())
    .use(router.allowedMethods());

// 开启服务器监听
app.listen(2022, () => {
    console.log("#localhost:2022");
})